package com.rpcLearning.server;

import com.rpcLearning.common.ReflectUtils;
import com.rpcLearning.proto.Request;
import com.rpcLearning.proto.ServiceDescriptor;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author:zyh
 * @Time:2021-03-17-19:17
 * @email:1269231889@qq.com
 * 管理rpc暴露的服务
 */
@Slf4j
public class ServiceManager {
    //作为注册中心，替代了zookeeper的作用
    private Map<ServiceDescriptor,ServiceInstance> service;

    public ServiceManager(){
        //为了保证安全性
        this.service = new ConcurrentHashMap<>();
    }

    //bean为单例，interface为暴露的接口，bean为实现interface的具体类
    public <T> void register(Class<T> interfaceClass, T bean){

        //这个地方不能getClass，直接使用interfaceClass，就好了，因为interfaceClass本身就是Class对象
        //如果使用getClass方法，返回的时java.lang.Class类，这就会导致得到所有的Object的public方法。
        Method[] methods = ReflectUtils.getPublicMethod(interfaceClass);
        for (Method method : methods) {
            ServiceInstance instance = new ServiceInstance(bean, method);
            ServiceDescriptor descriptor = ServiceDescriptor.from(interfaceClass, method);
            service.put(descriptor, instance);
            log.info("register service:{} {}", descriptor.getClazz(), descriptor.getMethod());
        }
    }
    /*
    * 进行查询服务
    * @param request
    * @return ServiceInstance
    * */
    public ServiceInstance lookup(Request req){
        ServiceDescriptor serviceDescriptor = req.getService();
        return  service.get(serviceDescriptor);
    }
}
